import { createClient } from 'redis';
import config from './configuration.js';
import log from './logger.js';
import mysqlHelper from './mysqlHelper.js';

const clientMap = new Map();
let subscriber; // 全局订阅者

async function ensureKeyspaceNotifications(client) {
    const notifyConfig = await client.configGet('notify-keyspace-events');
    if (!notifyConfig || !notifyConfig['notify-keyspace-events'].includes('E')) {
        const newConfig = (notifyConfig['notify-keyspace-events'] || '') + 'E';
        await client.configSet('notify-keyspace-events', newConfig);
        console.log('已启用过期通知: E');
    }
}
/**
 *
 * @param {*} db_index
 * @returns 
 */
async function getClient(db_index = 0) {
    if (clientMap.has(db_index)) {
        return clientMap.get(db_index);
    } else {
        console.log('redisConfig', config.redisConfig);
        let client = createClient({ url: `${config.redisConfig}/${db_index}` });
        client.on('error', (err) => log.error('Redis Client Error', err));
        client.on('ready', () => log.info('Redis Client Ready'));
        client.on('end', () => log.warn('Redis Client End'));
        client.on('reconnecting', () => log.warn('Redis Client reconnecting'));

        await client.connect();
        clientMap.set(db_index, client);

        // 确保启用键空间通知
        await ensureKeyspaceNotifications(client);

        // 初始化订阅者（只执行一次）
        if (!subscriber) {
            subscriber = client.duplicate();
            await subscriber.connect();
            // 修正订阅回调函数
            subscriber.subscribe(`__keyevent@${db_index}__:expired`, (err) => {
                if (err) {
                    console.log('err',JSON.stringify(err));
                    console.error('订阅失败:', err);
                    return;
                }
                console.log(`成功订阅 __keyevent@${db_index}__:expired 频道`);
            });
            subscriber.on('message', (channel, message) => {
                console.log(`接收到过期事件: ${message} 来自频道: ${channel}`);
            });
        }

        return client;
    }
}

async function closeAllClients() {
    for (const client of clientMap.values()) {
        await client.quit();
    }
    if (subscriber) {
        await subscriber.quit();
    }
    console.log('所有 Redis 客户端已关闭');
}

//获取24-48小时内的随机失效时间
function getRandomExpireTime() {
    let time = 24 * 60 * 60 + Math.floor(Math.random() * 24 * 60 * 60);
    return time;
}

async function setAutoExpire(key, value, db_index = 0) {
    let client = await getClient(db_index);
    await client.set(key, value, {
        EX: getRandomExpireTime(),
    });
}
async function set(key, value, ExpireTime = null, db_index = 0) {
    let client = await getClient(db_index);
    await client.set(key, value, {
        EX: ExpireTime,
    });
}
async function get(key, db_index = 0) {
    let client = await getClient(db_index);
    return await client.get(key);
}
async function del(key, db_index = 0) {
    let client = await getClient(db_index);
    return await client.del(key);
}
async function setnx(key, value, ExpireTime = null, db_index = 0) {
    let client = await getClient(db_index);
    const setResult = await client.setNX(key, value);

    if (setResult && ExpireTime) {
        // 如果设置成功，则设置过期时间
        await client.expire(key, ExpireTime);
    }

    return setResult;
}
/*
rediskey 查询和存储
tablename 表名
data 查询参数
*/
async function getandset(rediskey, tablename, data, db_index = 0) {
    let redisdata = await get(rediskey, db_index);
    if (!redisdata || redisdata == {}) {
        try {
            const findonedata = await mysqlHelper.findOne(tablename, data);
            if (findonedata) {
                await setAutoExpire(rediskey, JSON.stringify(findonedata), db_index);
                redisdata = JSON.stringify(findonedata);
            }
        } catch (error) {
            return error;
        }
    }
    return JSON.parse(redisdata);
}
export default {
    setAutoExpire,
    set,
    get,
    getandset,
    getClient,
    del,
    setnx,
};
